package com.company.project.service.impl;

import com.company.project.core.Result;
import com.company.project.core.ResultGenerator;
import com.company.project.dao.*;
import com.company.project.model.*;
import com.company.project.service.SysResAuthService;
import com.company.project.core.AbstractService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;


/**
 * Created by CodeGenerator on 2020/04/18.
 */
@Service
@Transactional
public class SysResAuthServiceImpl extends AbstractService<SysResAuth> implements SysResAuthService {
    @Resource
    private SysResAuthMapper sysResAuthMapper;
    @Resource
    private SysRoleAuthMapper sysRoleAuthMapper;
    @Resource
    private SysFunctionMapper sysFunctionMapper;
    @Resource
    private SysUserMapper sysUserMapper;

    @Override
    @Transactional
    public Result batchAddResAuth(int roleId, List<HashMap<String, Integer>> res) {
        for (HashMap<String, Integer> map : res) {
            SysResAuth resAuth = new SysResAuth();
            resAuth.setRoleId(roleId);
            resAuth.setStatus((short)1);
            resAuth.setFunctionId(map.get("functionId"));
            save(resAuth);
        }
        return ResultGenerator.genSuccessResult();
    }

    @Override
    @Transactional
    public Result batchUpdateResAuth(int roleId, List<HashMap<String, Integer>> res) {
        //删除原有权限
        HashMap<String,Object> condition = new HashMap<>();
        condition.put("roleId",roleId);
        sysResAuthMapper.deleteByCondition(condition);
        Result responseResult = batchAddResAuth(roleId, res);
        if (!ResultGenerator.isSuccess(responseResult)){
            return ResultGenerator.genFailResult();
        }
        return ResultGenerator.genSuccessResult();
    }

    @Override
    public Result queryResAuthList(int userId) {
        try {
            List<SysRoleAuth> roleAuthList = sysRoleAuthMapper.getRoleAuthList(userId, 1);
            List<SysFunction> result = new ArrayList<SysFunction>();
            if (null != roleAuthList && !roleAuthList.isEmpty()){
                for (SysRoleAuth roleAuth : roleAuthList) {
                    List<SysFunction> sysResAuths = sysResAuthMapper.queryFunctionList(roleAuth.getRoleId());
                    if (!StringUtils.isEmpty(sysResAuths)){
                        result.addAll(sysResAuths);
                    }
                }
            }
            return ResultGenerator.genSuccessResult(result);
        }catch (Exception e){
            e.printStackTrace();
            return ResultGenerator.genFailResult();
        }

    }

    @Override
    public Result queryResListTreeByRole(int roleId,int functionId,int type) {
        try {
            List<SysResAuth> sysResAuths = sysResAuthMapper.queryResAuthList(roleId);
            List<SysFunctionTreeDto> list = new ArrayList<SysFunctionTreeDto>();
            List<SysFunctionTreeDto> childrenTree = getChildrenTree(list, sysResAuths, functionId, type);
            return ResultGenerator.genSuccessResult(childrenTree);
        }catch (Exception e){
            e.printStackTrace();
            return ResultGenerator.genFailResult();
        }

    }


    public Result getResAuth(int roleId,int parentFunction) {
        try {
            List<SysResAuth> sysResAuths = sysResAuthMapper.getResAuthListByParent(roleId,parentFunction);
            if (null != sysResAuths && sysResAuths.size()>0){
                return ResultGenerator.genSuccessResult(sysResAuths);
            }else{
                return ResultGenerator.genFailResult();
            }

        }catch (Exception e){
            e.printStackTrace();
            return ResultGenerator.genFailResult();
        }
    }

    @Override
    public List<SysFunctionTreeDto> getChildrenTree(List<SysFunctionTreeDto> functionList, List<SysResAuth> sysResAuths
            , int functionId, int type){
        List<SysFunction> sysFunctionList = selectByParentId(functionId, type);
        if (null == sysFunctionList || sysFunctionList.size() == 0){
            return functionList;
        }else {
            HashSet<Integer> set = new HashSet<Integer>();
            if (null != sysResAuths && sysResAuths.size() >0){
                //判断是否被选中
                for (SysResAuth ResAuth : sysResAuths) {
                    set.add(ResAuth.getFunctionId());
                }
            }
            for (SysFunction function : sysFunctionList) {
                SysFunctionTreeDto sysFunctionTreeDto = new SysFunctionTreeDto();
                sysFunctionTreeDto.setKey(function.getId());
                sysFunctionTreeDto.setLabel(function.getFunctionName());
                sysFunctionTreeDto.setSpread(false);
                sysFunctionTreeDto.setChecked(false);
                if (set.contains(function.getId())){
                    sysFunctionTreeDto.setChecked(true);
                }
                List<SysFunction> sysFunctions = selectByParentId(function.getId(), type);
                if (null != sysFunctions && sysFunctions.size()>0){
                    List<SysFunctionTreeDto> childrenList = new ArrayList<SysFunctionTreeDto>();
                    sysFunctionTreeDto.setChildren(getChildrenTree(childrenList,sysResAuths,function.getId(),type));
                    sysFunctionTreeDto.setChecked(false);
                    functionList.add(sysFunctionTreeDto);
                }else {
                    functionList.add(sysFunctionTreeDto);
                    continue;
                }
            }
            return functionList;
        }

    }

    /**
     * 查询子功能
     *
     * @param pId  父功能id
     * @param type 功能类型
     * @return
     */
    @Override
    public List<SysFunctionMenuDto> queryMenuListByPid(List<SysFunctionMenuDto> functionList, HashSet<Integer> resAuths, int pId, int type) {
        if (null == resAuths && resAuths.size()==0){
            return null;
        }
        List<SysFunction> sysFunctionList = selectByParentId(pId, type);
        if (null == sysFunctionList || sysFunctionList.size() == 0){
            return functionList;
        }else {
            for (SysFunction function : sysFunctionList) {
                if (!resAuths.contains(function.getId())){
                    continue;
                }
                SysFunctionMenuDto sysFunctionMenuDto = new SysFunctionMenuDto();
                sysFunctionMenuDto.setKey(function.getId());
                sysFunctionMenuDto.setName(function.getFunctionName());
                sysFunctionMenuDto.setUrl(function.getFunctionPath());
                sysFunctionMenuDto.setType("1");
                List<SysFunction> sysFunctions = selectByParentId(function.getId(), type);
                if (null != sysFunctions && sysFunctions.size()>0){
                    sysFunctionMenuDto.setType("0");
                    List<SysFunctionMenuDto> childrenList = new ArrayList<SysFunctionMenuDto>();
                    sysFunctionMenuDto.setList(queryMenuListByPid(childrenList,resAuths,function.getId(),type));
                    functionList.add(sysFunctionMenuDto);
                }else {
                    functionList.add(sysFunctionMenuDto);
                    continue;
                }
            }
            return functionList;
        }
    }

    /**
     * 查询子菜单（不查询子集）
     * @param pId 父id
     * @param type 类型
     * @return
     */
    @Override
    public List<SysFunction> selectByParentId(int pId,int type){
        List<SysFunction> functionList = sysFunctionMapper.selectByParentId(pId, type);
        return functionList;
    }

    /**
     * 查询子菜单（不查询子集）
     *
     * @param pId  父id
     * @param type 类型
     * @return
     */
    @Override
    public List<SysFunction> selectByParentIdPlus(int pId, int type,int userId) {
        List<SysFunction> result = new ArrayList<SysFunction>();
        List<SysFunction> functionList = selectByParentId(pId,type);
        Result roleAuthList = queryResAuthList(userId);
        if (null == roleAuthList || !ResultGenerator.isSuccess(roleAuthList) || roleAuthList.getData() == null){
            return null;
        }
        SysUser user = sysUserMapper.selectByPrimaryKey(userId);
        Set<Integer> integerSet = new HashSet<>();
        List<SysFunction> functions = (List<SysFunction>)roleAuthList.getData();
        for (SysFunction function : functionList) {
            for (SysFunction sysFunction : functions) {
                if (sysFunction.getId().equals(function.getId())){
                    if (integerSet.isEmpty() || !integerSet.contains(function.getId())){
                        result.add(function);
                        integerSet.add(function.getId());
                    }
                    continue;
                }
            }
        }
        return result;
    }

    /**
     * 查询菜单
     *
     * @param userId
     * @param type
     * @return
     */
    @Override
    public Result getFunctionByUser(int userId, int type,int currentId) {
        try {
            List<SysFunction> functionByUser = sysResAuthMapper.getFunctionByUser(userId, type,currentId);
            return ResultGenerator.genSuccessResult(functionByUser);
        }catch (Exception e){
            e.printStackTrace();
            return ResultGenerator.genFailResult();
        }
    }

    /**
     * 查询菜单
     *
     * @param userId
     * @param type
     * @return
     */
    @Override
    public Result getFunctionTreeByUser(int userId, int type,int currentId) {
        try {
            List<SysFunction> functionByUser = sysResAuthMapper.getFunctionByUser(userId, type,currentId);
            List<HashMap<String,Object>> list = new ArrayList<HashMap<String,Object>>();
            for (SysFunction sysFunction : functionByUser) {
                HashMap<String,Object> temp = new HashMap<String,Object>();
                temp.put("key",sysFunction.getId());
                temp.put("label",sysFunction.getFunctionName());
                list.add(temp);
            }
            return ResultGenerator.genSuccessResult(list);
        }catch (Exception e){
            e.printStackTrace();
            return ResultGenerator.genFailResult();
        }
    }

    /**
     * 查询菜单
     *
     * @param roleId
     * @param type
     * @return
     */
    @Override
    public Result getFunctionTreeByRole(int roleId, int type,Integer currentId) {
        try {
            List<SysFunction> functionByUser = sysResAuthMapper.getFunctionByRole(roleId, type,currentId);
            List<HashMap<String,Object>> list = new ArrayList<HashMap<String,Object>>();
            for (SysFunction sysFunction : functionByUser) {
                HashMap<String,Object> temp = new HashMap<String,Object>();
                temp.put("key",sysFunction.getId());
                temp.put("label",sysFunction.getFunctionName());
                list.add(temp);
            }
            return ResultGenerator.genSuccessResult(list);
        }catch (Exception e){
            e.printStackTrace();
            return ResultGenerator.genFailResult();
        }
    }

}
